Notification Service
Author(s)
- Faizal Khan
Last Updated Date
2026-01-13
SRS References
Version History
| Version | Date | Changes | Author |
|---|---|---|---|
| 1.0 | 2026-01-13 | Initial draft for Notification Service architecture, APIs and features | Faizal Khan |
centralized Notification Platform
Feature Overview
Objective
Implement a centralized notification service that handles all communication with users (Customers and Dealers) across multiple channels. The service acts as a unified gateway for dispatching messages, ensuring consistent communication and centralized management of user preferences.
The service supports four primary delivery channels:
-
Push Notifications (FCM):
Real-time alerts sent to mobile devices and web browsers using Firebase Cloud Messaging (FCM). Handles token management and platform-specific payloads (iOS, Android, Web). -
In-App Notifications:
Persistent notifications visible within the application interface. Users can view history, mark items as read, and manage their notification inbox. -
Email Notifications:
Transactional emails (e.g., Welcome, Bid Updates, Reset Password) sent via SMTP. Supports HTML templates and attachments. -
SMS Notifications:
Urgent alerts and verification codes sent directly to user mobile numbers via Twilio.
The service is designed to be event-driven, consuming messages from other services (like Auction Engine, Identity Service) to trigger notifications asynchronously, ensuring high performance and decoupling.
Scope
This Service covers the following features:
-
Device Token Management:
- Registration of FCM tokens for devices.
- Automatic handling of token updates and deletions.
-
In-App Notification Center:
- deeply integrated inbox for users to view past alerts.
- Read/Unread status tracking.
- Categorization (Bids, Messages, System, etc.).
-
User Preference Management:
- Users can toggle specific notification types (e.g., turn off Push for marketing).
-
Multi-Channel Dispatching:
- unified logic to send a single notification event to multiple channels based on user preference and priority.
-
Real-Time Broadcasting:
- Integration with SignalR (via Auction Engine) to show notifications instantly while the user is online.
Dependencies
To support this service, the following systems must be integrated:
- Identity Service (IAM) – To validate users and retrieve contact details (Email, Phone).
- Auction Engine Service – Major source of events (New Bid, Auction Ended) and handler for SignalR broadcasting.
- Firebase Cloud Messaging (FCM) – For sending push notifications.
- Twilio – For sending SMS messages.
- SMTP Server / Microsoft Graph – For sending emails.
- Message Bus (RabbitMQ/MassTransit) – For receiving notification triggers from other microservices.
Requirements
Functional Requirements
1. Device Token Lifecycle
- Mobile and Web clients must register their FCM tokens upon login.
- Tokens must be associated with the specific logged-in user.
- System must handle token invalidation and refreshment.
- Support for multiple devices per user.
2. In-App Notification Management
- Users must be able to:
- Fetch a paginated list of notifications.
- Filter by category (e.g., Bids, System).
- Mark individual or all notifications as read.
- Delete notifications to clean up their inbox.
- Real-time delivery: When an in-app notification is generated, it should be immediately pushed to the client via SignalR if the user is online.
3. Notification Dispatching
- The system handles a generic
NotificationRequestwhich specifies:- Recipient: User details (Email, Phone, Device Tokens).
- Channels: List of desired channels (Email, SMS, Push).
- Type: The specific event type (e.g.,
BidAccepted). - Payload: Dynamic data to fill templates.
- Templates: Email and SMS content must be generated from pre-defined templates to ensure consistency.
4. Event-Driven Architecture
- The service must act as a consumer for platform events.
- Example: When a bid is placed in
AuctionEngine, a message is published.NotificationServiceconsumes this and triggers the appropriate alerts to the Customer.
Non-Functional Requirements
1. Reliability
- Notifications (especially transactional ones like OTPs or detailed Bid info) must not be lost.
- Implementation of retry policies for failed dispatches (e.g., if SMTP is down).
2. Scalability
- Must handle bursts of notifications (e.g., 1000 dealers notified of a new hot auction simultaneously).
- Asynchronous processing via message queues prevents blocking the main thread.
3. Latency
- Push and In-App notifications should be delivered within seconds of the event occurrence.
Data Models
1. Notification Request Models (Internal/Contract)
public record NotificationRequest
{
public required IReadOnlyDictionary<string, string> Data { get; set; }
public required List<DeliveryMethod> DeliveryMethods { get; set; }
public required NotificationType NotificationType { get; set; }
public required UsersComDetails SendTo { get; set; }
public List<Attachment>? Attachments { get; set; }
}
public record UsersComDetails
{
public string? Name { get; set; }
public required string Email { get; set; }
public required string Phone { get; set; }
public List<string>? DeviceToken { get; set; }
}
public enum DeliveryMethod
{
Email = 0,
SMS = 1,
Push = 2
}
public enum NotificationType
{
None = 0,
ResetPassword = 1,
UserWelcome = 2,
NotifyDealersAboutNewAuction = 3,
NewDealerCreate = 4,
BidAccepted = 5,
NewLowestBidPlaced = 6,
AuctionOneDayReminder = 7,
DealerOutbidAlert = 8,
NonLowestBidPlaced = 9,
}
2. Device Token Models
public record RegisterDeviceRequest(
string DeviceId,
string FcmToken,
Platform Platform
);
public record DeviceToken
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public string DeviceId { get; set; }
public string FcmToken { get; set; }
public Platform Platform { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
public enum Platform
{
Android,
iOS,
Web
}
3. In-App Notification Models
public record InAppNotificationFilter : CursorPaginationFilter
{
public InAppNotificationCategory? Category { get; init; }
public bool? IsRead { get; init; }
}
public record Notification
{
public Guid NotificationId { get; set; }
public Guid UserId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public InAppNotificationCategory Category { get; set; }
public bool IsRead { get; set; }
public string? ActionName { get; set; }
public string? ActionValue { get; set; }
public string? Image { get; set; }
public DateTime CreatedAt { get; set; }
}
public enum InAppNotificationCategory
{
All = 0,
Bids = 1,
Messages = 2,
Auctions = 3,
Systems = 4
}
API Interfaces
| Endpoint | Method | Parameters | Response | Response Status Codes |
|---|---|---|---|---|
/device/register | POST | RegisterDeviceRequest | CommonResponse | 200, 400, 401, 500 |
/device/{deviceId} | DELETE | string deviceId | CommonResponse | 200, 400, 401, 404, 500 |
/in-app | GET | InAppNotificationFilter | ResponseWithData<object> | 200, 400, 401, 500 |
/in-app/mark-as-read | PUT | MarkAsReadRequest | CommonResponse | 200, 400, 401, 404, 500 |
/in-app/delete | DELETE | DeleteNotificationRequest | CommonResponse | 200, 400, 401, 404, 500 |
/settings | PUT | UpdatePushNotificationRequest | CommonResponse | 200, 400, 401, 404, 500 |
/settings | GET | None | NotificationSettingsResponse | 200, 401, 404, 500 |
API Request & Response Examples
1. Register Device Token
Endpoint: POST /device/register
Request Body:
{
"deviceId": "unique-device-id-123",
"fcmToken": "fcm-registration-token-abc-xyz",
"platform": 2
}
Note: Platform Enum: 0=Android, 1=iOS, 2=Web
Response Body:
{
"status": 0,
"message": "Device token registered successfully"
}
2. Get In-App Notifications
Endpoint: GET /in-app?pageNumber=1&rowsPerPage=10&isRead=false
Response Body:
{
"data": [
{
"notificationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"userId": "3fa85f64-5717-4562-b3fc-2c963f66afa1",
"title": "New Bid Received",
"description": "Dealer XYZ placed a bid of $25,000 on your Camry.",
"category": 1,
"isRead": false,
"ActionName": "OPEN_AUCTION_DETAILS",
"ActionValue": "dad15c4a-9bb0-4bdf-b815-b26061d55de3",
"image": "https://example.com/icon.png",
"createdAt": "2024-09-15T10:30:00Z"
}
],
"totalNumber": 5,
"hasPreviousPage": false,
"hasNextPage": true
}
3. Mark Notification as Read
Endpoint: PUT /in-app/mark-as-read
Request Body:
{
"notificationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"markAll": false
}
Response Body:
{
"status": 0,
"message": "Notification(s) marked as read successfully"
}
Message Consumers (Internal APIs)
The Notification Service subscribes to various MassTransit events to trigger actions.
1. AddInAppNotificationConsumer
Queue/Topic: AddInAppNotificationRequest
Purpose:
- Receives a request to create a permanent in-app notification.
- Persists the notification to the database.
- Broadcasting: Publishes a
BroadcastInAppNotificationRequestevent. This secondary event is picked up by theAuctionEngineServiceto push the notification to the user's active session via SignalR.
Message Contract:
public record AddInAppNotificationRequest
{
public Guid UserId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public InAppNotificationCategory Category { get; set; }
public bool IsRead { get; set; } = false;
public string? ActionName { get; set; }
public string? ActionValue { get; set; }
public string? Image { get; set; }
}
2. BatchNotificationConsumer
Queue/Topic: BatchNotificationRequest
Purpose: Handles sending notifications to multiple users at once (e.g., notifying all dealers about a new auction matching their inventory).
3. GetNotificationSettingsConsumer
Queue/Topic: GetNotificationSettingsRequest
Purpose: Responds to other services enquiring about a user's notification preferences.
3. GetActiveTokensConsumer
Queue/Topic: GetActiveTokensRequest
Purpose: Retrieves and sends list of actve tokens for sending push notifications.